﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace XNAVE3D
{
    class ModeloAnimation
    {
        Vector3 position;

        public Model[] model;

        public Matrix myWorld = Matrix.Identity; 
        
        Texture2D tex;

        int frame = 0;

        float contador;
               
        VertexPositionTexture[] verts;

        VertexBuffer vertexBuffer;

        short[] index;

        float[][] buffer;

        int size; 

        Vector2[] ct;

        Effect effect;

        public ModeloAnimation(Vector3 position, Model[] model, Texture2D tex, Effect e, GraphicsDevice g)
        {
            this.tex = tex;
            myWorld.Translation = position; 
            this.position = position;
            this.model = model;
            effect = e;
            size = model[0].Meshes[0].MeshParts[0].VertexBuffer.VertexCount;
            buffer = new float[model.Length][];
            for (int i = 0; i < model.Length; i++)
            {
                buffer[i] = new float[size * 8];
                model[i].Meshes[0].MeshParts[0].VertexBuffer.GetData<float>(buffer[i]);
            }
            index = new short[model[0].Meshes[0].MeshParts[0].IndexBuffer.IndexCount];
            model[0].Meshes[0].MeshParts[0].IndexBuffer.GetData<short>(index);
            verts = new VertexPositionTexture[size];
            vertexBuffer = new VertexBuffer(g, typeof(VertexPositionTexture),
                verts.Length, BufferUsage.None);
            vertexBuffer.SetData<VertexPositionTexture>(verts);
            ct = new Vector2[size];
            int k = frame;
            int l = frame+1;
            if (l == model.Length)
            {
                l = 0;
            }
            for (int i = 0; i < size; i++)
            {
                int j = i * 8;
                Vector3 pos = new Vector3(this.buffer[k][j], -buffer[k][j+2], -buffer[k][j+1]);
                ct[i] = new Vector2(this.buffer[0][j + 6], buffer[0][j + 7]);
                verts[i] = new VertexPositionTexture(pos, ct[i]);
            }

            myWorld *= Matrix.CreateScale(5);

        }
        
        float divisor = 0.001f;

        public void Update(GameTime gameTime, GraphicsDevice g)
        {
            myWorld.Translation = position;

            if (Keyboard.GetState().IsKeyDown(Keys.Up) && divisor > 0)
            {
                divisor -= 0.0005f;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Down) && divisor < 0.01f)
            {
                divisor += 0.0005f;
            }

            contador += (float)gameTime.ElapsedGameTime.TotalMilliseconds * divisor;

            if (contador >= 1.0f)
            {
                contador = 0;
                if (frame == model.Length - 1)
                {
                    frame = 0;
                }
                else
                {
                    frame++;
                }   
            }

            size = model[0].Meshes[0].MeshParts[0].VertexBuffer.VertexCount;

            buffer = new float[model.Length][];

            for (int i = 0; i < model.Length; i++)
            {
                buffer[i] = new float[size * 8];
                model[i].Meshes[0].MeshParts[0].VertexBuffer.GetData<float>(buffer[i]);
            }

            index = new short[model[0].Meshes[0].MeshParts[0].IndexBuffer.IndexCount];

            model[0].Meshes[0].MeshParts[0].IndexBuffer.GetData<short>(index);

            verts = new VertexPositionTexture[size];

            vertexBuffer = new VertexBuffer(g, typeof(VertexPositionTexture),
                verts.Length, BufferUsage.None);

            vertexBuffer.SetData<VertexPositionTexture>(verts);

            ct = new Vector2[size];

            int k = frame;

            int l = frame + 1;

            if (l == model.Length)
            {
                l = 0;
            }

            for (int i = 0; i < size; i++)
            {
                int j = i * 8;

                Vector3 pos = new Vector3(this.buffer[k][j], -buffer[k][j + 2], buffer[k][j + 1]) * (1 - contador) + new Vector3(this.buffer[l][j], -buffer[l][j + 2], buffer[l][j + 1]) * contador;

                ct[i] = new Vector2(this.buffer[0][j + 6], buffer[0][j + 7]);

                verts[i] = new VertexPositionTexture(pos, ct[i]);
            }
        }

        public void Draw(Matrix view, Matrix projection, GraphicsDevice g)
        {
            g.SetVertexBuffer(vertexBuffer);
            effect.CurrentTechnique = effect.Techniques["Technique1"];
            effect.Parameters["View"].SetValue(view);
            effect.Parameters["Projection"].SetValue(projection);
            effect.Parameters["World"].SetValue(myWorld);
            effect.Parameters["colorTexture"].SetValue(tex);
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                g.DrawUserIndexedPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, verts, 0, verts.Length, index,0,index.Length/3);
            }                 
        }
    }
}
